#include "system_manager.h"
#include "web_server.h"
#include "base_log.h"
#include <nlohmann/json.hpp>
#include "upgrade.h"
#include "base_utils.h"
#include <filesystem>
#include <fstream>
#include <vector>
#include <string>
#include <chrono>
#include <iomanip>
#include <sstream>
#include "common_version.h"
#include "common_product_definition.h"

namespace El {
namespace Restful {

using json = nlohmann::json;

// 生成基于时间戳的唯一ID
std::string GenerateUpgradeId()
{
    auto now = std::chrono::system_clock::now();
    auto now_ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
    std::stringstream ss;
    ss << "upgrade-" << now_ms.count();
    return ss.str();
}

// API处理器实现
WebServer::HttpResponse HandleSystemReboot(const WebServer::HttpRequest &req)
{
    WebServer::HttpResponse response;
    response.content_type = "application/json";
    json result;

    // 解析请求参数（如果有）
    bool force = false;
    int delay = 0;

    if (!req.body.empty()) {
        // 尝试解析JSON
        json request_data = json::parse(req.body, nullptr, false);
        if (request_data.is_discarded()) {
            // JSON解析失败，返回错误
            result["code"] = 400;
            result["message"] = "Invalid JSON format";
            result["data"] = nullptr;
            result["error"] = {{"code", 400}, {"message", "Invalid JSON format"}};

            response.status_code = 400;
            response.body = result.dump();
            return response;
        }

        // 提取参数
        if (request_data.contains("force") && request_data["force"].is_boolean()) {
            force = request_data["force"].get<bool>();
        }

        if (request_data.contains("delay") && request_data["delay"].is_number()) {
            delay = request_data["delay"].get<int>();
        }
    }

    // 执行重启操作
    if (SystemManager::GetInstance().RestartDevice(delay, force)) {
        // 获取当前时间作为计划重启时间
        auto now = std::chrono::system_clock::now();
        // 如果有延迟，则加上延迟时间
        if (delay > 0) {
            now += std::chrono::seconds(delay);
        }
        auto now_time = std::chrono::system_clock::to_time_t(now);
        std::stringstream ss;
        ss << std::put_time(std::gmtime(&now_time), "%Y-%m-%dT%H:%M:%SZ");

        result["code"] = 200;
        result["message"] =
            delay > 0 ? "Device will reboot after " + std::to_string(delay) + " seconds" : "Device is rebooting...";
        result["data"] = {{"status", "success"}, {"estimated_boot_time", 60}, {"scheduled_time", ss.str()}};
        result["error"] = nullptr;

        response.status_code = 200;
    } else {
        result["code"] = 500;
        result["message"] = "Failed to restart device";
        result["data"] = nullptr;
        result["error"] = {{"code", 500}, {"message", "Failed to restart device"}};

        response.status_code = 500;
    }

    response.body = result.dump();
    return response;
}

WebServer::HttpResponse HandleSystemInfo(const WebServer::HttpRequest &req)
{
    (void)req;
    WebServer::HttpResponse response;
    response.content_type = "application/json";

    // 获取设备型号
    std::string model;
    if (!Common::ProductDefinition::GetInstance().GetValue("device_model", model)) {
        LOG_ERROR("获取设备型号失败");
        model = "未知设备";
    }

    // 获取固件版本
    std::string version;
    version = Common::VersionManager::GetInstance().GetVersionFull();
    if (version.empty()) {
        LOG_ERROR("获取固件版本失败");
        version = "未知版本";
    }

    // 获取设备序列号
    std::string serial_number;
    if (!Common::ProductDefinition::GetInstance().GetValue("serial_number", serial_number)) {
        LOG_ERROR("获取设备序列号失败");
        serial_number = "未知序列号";
    }

    json data = {{"code", 200},
                 {"message", "OK"},
                 {"status", "success"},
                 {"data", {{"model", model}, {"firmware_version", version}, {"serial_number", serial_number}}}};
    response.status_code = 200;
    response.body = data.dump();
    return response;
}

WebServer::HttpResponse HandleFirmwareUpload(const WebServer::HttpRequest &req)
{
    WebServer::HttpResponse response;
    response.content_type = "application/json";
    json result;

    try {
        json request_data = json::parse(req.body);
        int chunkIndex = request_data["chunk_index"].get<int>();
        int totalChunks = request_data["total_chunks"].get<int>();
        std::string chunkDataBase64 = request_data["chunk_data"].get<std::string>();

        auto &systemManager = SystemManager::GetInstance();

        // 如果是第一个分块，初始化升级
        if (chunkIndex == 0) {
            auto fileInfo = request_data["file_info"];
            std::string filename = fileInfo["name"].get<std::string>();
            size_t filesize = fileInfo["size"].get<size_t>();
            std::string version = fileInfo["version"].get<std::string>();
            std::string md5 = fileInfo["md5"].get<std::string>();

            if (!systemManager.InitializeUpgrade(filename, filesize, version, md5, totalChunks)) {
                throw std::runtime_error("Failed to initialize upgrade");
            }
        }

        // 处理分块数据
        if (!systemManager.HandleChunkData(chunkDataBase64, chunkIndex, totalChunks)) {
            throw std::runtime_error("Failed to handle chunk data");
        }

        // 按照API文档格式构造成功响应
        result["code"] = 200;
        result["message"] = "Chunk uploaded successfully";
        result["data"] = {{"status", "success"}, {"progress", systemManager.GetUpgradeProgress()}};
        result["error"] = nullptr;

        response.status_code = 200;

    } catch (const std::exception &e) {
        // 按照API文档格式构造错误响应
        result["code"] = 400;
        result["message"] = e.what();
        result["data"] = nullptr;
        result["error"] = {{"code", 400}, {"message", e.what()}};

        response.status_code = 400;
    }

    response.body = result.dump();
    return response;
}

WebServer::HttpResponse HandleFirmwareStatus(const WebServer::HttpRequest &req)
{
    (void)req;
    WebServer::HttpResponse response;
    response.content_type = "application/json";
    json result;

    try {
        auto &systemManager = SystemManager::GetInstance();
        std::string statusStr;

        switch (systemManager.GetUpgradeStatus()) {
            case El::Upgrade::UpgradeStatus::IDLE:
                statusStr = "idle";
                break;
            case El::Upgrade::UpgradeStatus::DOWNLOADING:
                statusStr = "downloading";
                break;
            case El::Upgrade::UpgradeStatus::VERIFYING:
                statusStr = "verifying";
                break;
            case El::Upgrade::UpgradeStatus::UPGRADING:
                statusStr = "upgrading";
                break;
            case El::Upgrade::UpgradeStatus::SUCCESS:
                statusStr = "success";
                break;
            case El::Upgrade::UpgradeStatus::FAILED:
                statusStr = "error";
                break;
            case El::Upgrade::UpgradeStatus::ROLLBACK:
                statusStr = "rollback";
                break;
            default:
                statusStr = "unknown";
        }

        result["code"] = 200;
        result["message"] = "OK";
        result["data"] = {{"status", statusStr},
                          {"progress", systemManager.GetUpgradeProgress()},
                          {"message", systemManager.GetUpgradeMessage()}};
        result["error"] = nullptr;

        response.status_code = 200;
    } catch (const std::exception &e) {
        result["code"] = 400;
        result["message"] = e.what();
        result["data"] = nullptr;
        result["error"] = {{"code", 400}, {"message", e.what()}};

        response.status_code = 400;
    }

    response.body = result.dump();
    return response;
}

WebServer::HttpResponse HandleFirmwareUpgrade(const WebServer::HttpRequest &req)
{
    WebServer::HttpResponse response;
    response.content_type = "application/json";
    json result;

    try {
        json request_data = json::parse(req.body);

        // 验证必需字段
        if (!request_data.contains("version")) {
            throw std::runtime_error("Missing required field: version");
        }

        std::string version = request_data["version"].get<std::string>();

        // 处理可选的计划升级时间
        std::string schedule_time;
        if (request_data.contains("schedule_time")) {
            schedule_time = request_data["schedule_time"].get<std::string>();
        }

        // 开始升级流程
        if (SystemManager::GetInstance().StartUpgradeProcess()) {
            result["code"] = 200;
            result["message"] =
                schedule_time.empty() ? "Upgrade started successfully" : "Upgrade scheduled successfully";
            result["data"] = {
                {"upgrade_id", GenerateUpgradeId()},
                {"status", schedule_time.empty() ? "started" : "scheduled"},
                {"estimated_duration", 300} // 预计5分钟
            };

            if (!schedule_time.empty()) {
                result["data"]["schedule_time"] = schedule_time;
            }

            result["error"] = nullptr;
            response.status_code = 200;
        } else {
            throw std::runtime_error("Failed to start upgrade process");
        }
    } catch (const std::exception &e) {
        result["code"] = 400;
        result["message"] = e.what();
        result["data"] = nullptr;
        result["error"] = {{"code", 400}, {"message", e.what()}};
        response.status_code = 400;
    }

    response.body = result.dump();
    return response;
}

void RegisterSystemApiHandlers()
{
    // 注册各个API处理器
    WebServer::IHttpServer &server = WebServer::IHttpServer::GetInstance();
    server.RegisterHandler("POST", "^/v1/system/reboot$", HandleSystemReboot);
    server.RegisterHandler("GET", "^/v1/system/info$", HandleSystemInfo);
    server.RegisterHandler("POST", "^/v1/firmware/upload$", HandleFirmwareUpload);
    server.RegisterHandler("GET", "^/v1/firmware/status$", HandleFirmwareStatus);
    server.RegisterHandler("POST", "^/v1/firmware/upgrade$", HandleFirmwareUpgrade);
}

} // namespace Restful
} // namespace El